<template>
  <a-card>
    <a-row style="margin-bottom: 20px">
      <a-button type="primary" @click="addCol">添加栏目</a-button>
    </a-row>
    <a-table
      :columns="colColumns"
      :data-source="data.dataSource"
      :loading="data.loading"
      :pagination="false"
      rowKey="id"
    >
      <!-- 关联文章数 -->
      <template #quoteCount="{ record }">
        <span>{{ record.quoteCount || 0 }}</span>
        <i class="iconfont icon-xiayi12px"></i>
      </template>

      <!-- 排序 -->
      <template #sequence="{ record }">
        <a-input-number
          @change="changeColSort($event, record)"
          @blur="confirmColSort"
          :value="record.sequence"
        ></a-input-number>
      </template>

      <template #status="{ record: { status } }">
        <a-badge
          :color="status === 0 ? '#76db93' : '#ccc'"
          :text="status === 0 ? '显示' : '隐藏'"
        ></a-badge>
      </template>

      <!-- 操作 -->
      <template #handler="{ record }">
        <a @click="editCol(record)">编辑</a>
        <span style="color: #1890ff; margin: 0 6px">|</span>
        <a-dropdown>
          <a>更多</a>
          <template #overlay>
            <a-menu>
              <a-menu-item key="1" v-if="record.parentId !== 0">
                <a @click="getLinkArticle(record)">关联文章</a>
              </a-menu-item>
              <a-menu-item key="2">
                <a @click="changeStatus(record)">{{ record.status === 0 ? '隐藏' : '显示' }}</a>
              </a-menu-item>
              <a-menu-item
                key="3"
                v-if="record.parentId !== 0 && record.status === 0 && record.parentStatus === 0"
              >
                <a :href="`${VUE_APP_YXT_URL}?m=${record.id}`" target="_blank">打开链接</a>
              </a-menu-item>
              <a-menu-item key="4">
                <a @click="delCol(record)">删除</a>
              </a-menu-item>
            </a-menu>
          </template>
        </a-dropdown>
      </template>
    </a-table>
  </a-card>
  <a-modal v-model:visible="showHandlerCol" :title="title" @ok="confirmHandlerCol" @cancel="cancel">
    <a-row type="flex" justify="center">
      <a-form :model="colInfo" :rules="rules" ref="colForm">
        <a-form-item label="所属栏目" name="parentId">
          <a-select v-model:value="colInfo.parentId" style="width: 200px">
            <a-select-option :value="0">根目录</a-select-option>
            <a-select-option v-for="item in rootColumn" :key="item.id" :value="item.id">
              {{ item.columnName }}
            </a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item label="栏目名称" name="columnName">
          <a-input v-model:value="colInfo.columnName" style="width: 200px"></a-input>
        </a-form-item>
      </a-form>
    </a-row>
  </a-modal>
  <!-- 删除警告 -->
  <warning-modal
    title="删除栏目"
    content="删除栏目"
    v-model:visible="delColWarning"
    @confirm="confirmDelCol"
    @cancel="cancelWarning"
  >
    <a-row type="flex" justify="center" style="color: #8d8d8d">
      删除当前栏目将同时删除子栏目及解除所有文章关联数据
    </a-row>
  </warning-modal>
  <!-- 抽屉 -->
  <a-drawer
    placement="right"
    :title="linkArticleModal.title"
    :width="700"
    :visible="linkArticleModal.visible"
    @close="closeLinkArticle"
  >
    <div style="margin: 10px">
      <a-button type="primary" @click="linkColArticle">关联文章</a-button>
    </div>
    <a-table
      :columns="articleColumns"
      :loading="articleData.loading"
      :data-source="articleData.dataSource"
      :pagination="false"
      rowKey="id"
    >
      <!-- 浏览次数 -->
      <template #scanNum="{ record }">
        <span>
          <i class="iconfont icon-guankanshu-16px"></i>
          {{ record.scanNum || 0 }}
        </span>
      </template>

      <!-- 同意次数 -->
      <template #thumbsUp="{ record }">
        <span>
          <i class="iconfont icon-dianzan-16px"></i>
          {{ record.thumbsUp || 0 }}
        </span>
      </template>

      <!-- 反对次数 -->
      <template #thumbsDown="{ record }">
        <span>
          <i class="iconfont icon-fandui-32px"></i>
          {{ record.thumbsDown || 0 }}
        </span>
      </template>

      <template #sequence="{ record }">
        <a-input-number
          @change="changeArtSort($event, record)"
          @blur="confirmArtSort"
          :value="record.sequence"
        ></a-input-number>
      </template>

      <!-- 操作 -->
      <template #handler="{ record }">
        <a @click="dissociated(record)">解除关联</a>
      </template>
    </a-table>
    <a-row style="margin-top: 20px" type="flex" justify="end">
      <a-pagination
        show-quick-jumper
        showSizeChanger
        v-model:pageSize="pagination.limit"
        v-model:current="pagination.page"
        :total="pagination.total"
        @change="confirmGetLinkArticle"
        @showSizeChange="confirmGetLinkArticle"
      />
    </a-row>
  </a-drawer>
  <a-modal
    title="关联文章"
    :width="800"
    v-model:visible="showColArticle"
    @ok="validLinkArticle"
    @cancel="closeColArticle"
  >
    <list-transfer
      v-if="showColArticle"
      :selectList="tags"
      select-placeholder="选择文章标签"
      :dataSource="articleList.dataSource"
      v-model:inputValue="searchArticleInfo.keywords"
      v-model:selectValue="searchArticleInfo.labelId"
      v-model:value="linkArticleKey.articleIds"
      @select="confirmGetTagList"
      @scroll="scollGetArticle"
    ></list-transfer>
  </a-modal>
</template>
<script>
import { defineComponent, reactive, ref, toRaw, watch } from 'vue';
import { message } from 'ant-design-vue';
import { concatIds, disposeTransferList } from '@/utils/helper';
import {
  apiGetColumnList,
  apiAddColumn,
  apiEditColumn,
  apiEditColumnStatus,
  apiDelColumn,
  apiGetArticleColList,
  apiGetArticleList,
  apiGetArticleTagList,
  apiAddRelationdArticle,
  apiDissociated,
  apiEditRelationdArticle,
} from '@/api/articleManage';
import WarningModal from '@/components/warning-modal';
import ListTransfer from '@/components/list-transfer';
import { parseTime, findChildrenList } from '@/utils';
const transList = list => {
  return list.map(item => {
    item.createTimeStr = parseTime(item.createTime);
    if (item.parentId !== 0) {
      const parent = list.find(par => item.parentId === par.id);
      item.parentStatus = parent.status;
    }
    return item;
  });
};

// 栏目列表
const colColumns = [
  {
    title: '栏目名称',
    dataIndex: 'columnName',
    width: '30%',
  },
  {
    title: '关联文章数',
    dataIndex: 'quoteCount',
    slots: {
      customRender: 'quoteCount',
    },
  },
  {
    title: '排序',
    dataIndex: 'sequence',
    width: '5%',
    slots: {
      customRender: 'sequence',
    },
  },
  {
    title: '状态',
    dataIndex: 'status',
    slots: {
      customRender: 'status',
    },
  },
  {
    title: '创建时间',
    dataIndex: 'createTimeStr',
  },
  {
    title: '操作',
    dataIndex: 'handler',
    slots: {
      customRender: 'handler',
    },
  },
];

// 文章列表
const articleColumns = [
  {
    title: '关联文章',
    dataIndex: 'articleName',
    width: '30%',
  },
  {
    title: '浏览次数',
    dataIndex: 'scanNum',
    slots: {
      customRender: 'scanNum',
    },
  },
  {
    title: '赞同数',
    dataIndex: 'thumbsUp',
    slots: {
      customRender: 'thumbsUp',
    },
  },
  {
    title: '反对数',
    dataIndex: 'thumbsDown',
    slots: {
      customRender: 'thumbsDown',
    },
  },
  {
    title: '排序',
    dataIndex: 'sequence',
    width: '8%',
    slots: {
      customRender: 'sequence',
    },
  },
  {
    title: '操作',
    dataIndex: 'handler',
    slots: {
      customRender: 'handler',
    },
  },
];

export default defineComponent({
  name: 'helpCenter',
  setup() {
    // 根栏目
    const rootColumn = ref([]);

    let isLoading = false;

    // 分页
    // const pagination = reactive({ limit: 10, page: 1, total: 0 });

    /**
     * 获取栏目
     **/
    const data = reactive({ dataSource: [], loading: false });
    const confirmGetColumn = async () => {
      try {
        data.loading = true;
        const { list } = await apiGetColumnList({ type: 1 });
        const mapList = transList(list);
        data.dataSource = findChildrenList(mapList, 0);
        rootColumn.value = mapList.filter(item => item.parentId === 0);
      } finally {
        data.loading = false;
      }
    };
    confirmGetColumn();

    /**
     * 获取标签列表
     **/
    const tags = ref([]);
    const confirmGetTagList = (keywords = '') => {
      apiGetArticleTagList({ keywords }).then(res => {
        tags.value = res.list;
      });
    };

    /**
     * 获取所有文章列表
     **/
    const articleList = reactive({
      page: 1,
      limit: 10,
      isAll: false,
      loading: false,
      dataSource: [],
    });

    /**
     * 关闭关联文章弹框
     **/
    const closeColArticle = () => {
      showColArticle.value = false;
      linkArticleKey.articleIds = [];
    };

    // 文章id和栏目id
    const linkArticleKey = reactive({ articleIds: [] });

    /**
     * 将已经选中的选项添加到列表
     **/
    const disposeSelectList = (list, selectIds) => {
      const selectList = [];
      list.forEach(item => {
        const selectItem = selectIds.find(value => item.id === +value);
        if (selectItem) {
          selectList.push(item);
        }
      });
      return selectList;
    };

    /**
     * 过滤已经选中的元素，避免重复添加
     **/
    const filterSelect = (list, selectIds) =>
      list.filter(item => !selectIds.some(articleId => +articleId === item.id));

    /**
     * 获取文章列表
     **/
    const searchArticleInfo = reactive({ keywords: '', labelId: undefined });
    const confirmGetArticle = async () => {
      try {
        articleList.loading = true;
        const { page } = await apiGetArticleList({
          page: articleList.page,
          limit: articleList.limit,
          labelId: searchArticleInfo.labelId,
          keywords: searchArticleInfo.keywords,
        });
        // 保存已选中的列表元素，即使重新调用接口，但是已选中的列表元素不可删除，否则会出现选中后更新搜索条件，已选中的选项被清空
        const selectList = disposeSelectList(articleList.dataSource, linkArticleKey.articleIds);
        // 过滤选中列表中的元素，否则可能存在左右两边均有出现的可能
        const list = filterSelect(page.list, linkArticleKey.articleIds);
        articleList.dataSource = disposeTransferList([...selectList, ...list], 'articleName', 'id');
      } finally {
        articleList.loading = false;
      }
    };
    confirmGetArticle();

    /**
     * 滚动事件
     **/
    const scollGetArticle = args => {
      const clientHeight = args[1].target.clientHeight;
      const scrollTop = args[1].target.scrollTop;
      const scrollHeight = args[1].target.scrollHeight;
      if (clientHeight + scrollTop === scrollHeight && !articleList.isAll) {
        articleList.page++;
        confirmScroll();
      }
    };

    /**
     * 滚动获取数据
     **/
    const confirmScroll = async () => {
      try {
        articleList.loading = true;
        const { page } = await apiGetArticleList({
          page: articleList.page,
          limit: articleList.limit,
          labelId: searchArticleInfo.labelId,
          keywords: searchArticleInfo.keywords,
        });
        const list = filterSelect(page.list, linkArticleKey.articleIds);
        articleList.dataSource = disposeTransferList(
          [...articleList.dataSource, ...list],
          'articleName',
          'id',
        );
        if (page.list.length < articleList.limit) {
          articleList.isAll = true;
        }
      } finally {
        articleList.loading = false;
      }
    };

    watch(searchArticleInfo, () => {
      articleList.page = 1;
      articleList.isAll = false;
      confirmGetArticle();
    });

    const sequence = { number: '', info: {} };
    const changeColSort = (e, row = {}) => {
      sequence.number = e;
      sequence.info = toRaw(row);
    };

    /**
     * 修改排序
     **/
    const confirmColSort = () => {
      if (!sequence.number) {
        return;
      }
      confirmEditCol({ columnId: sequence.info.id, sequence: sequence.number });
    };

    // 删除栏目弹窗
    const delColWarning = ref(false);
    // 当前操作栏目信息
    const colInfo = reactive({
      parentId: 0,
      columnName: '',
      id: '',
      columnType: 1,
    });

    /**
     * 校验规则
     **/
    const rules = {
      parentId: {
        required: true,
        message: '根目录不能为空',
        trigger: 'change',
        type: 'number',
      },
      columnName: {
        required: true,
        message: '栏目名称不能为空',
        trigger: 'blur',
      },
    };

    /**
     * 删除栏目弹窗
     **/
    const delCol = row => {
      delColWarning.value = true;
      colInfo.id = row.id;
    };

    const title = ref('');
    const showHandlerCol = ref(false);
    /**
     * 添加栏目弹窗
     **/
    const addCol = () => {
      title.value = '添加栏目';
      showHandlerCol.value = true;
    };

    /**
     * 编辑栏目弹窗
     **/
    const editCol = row => {
      title.value = '编辑栏目';
      showHandlerCol.value = true;
      const parent = data.dataSource.find(item => row.parentId === item.id);
      colInfo.id = row.id;
      colInfo.parentId = parent ? parent.id : 0;
      colInfo.columnName = row.columnName;
    };

    /**
     * 更改状态
     **/
    const changeStatus = row => {
      const { id, status } = toRaw(row);
      confirmEditColStatus({ columnId: id, status: status === 0 ? 1 : 0, type: 2 });
    };

    const confirmEditColStatus = async params => {
      if (isLoading) return;
      try {
        isLoading = true;
        await apiEditColumnStatus(params);
        message.success('编辑成功');
        confirmGetColumn();
        cancel();
      } finally {
        isLoading = false;
      }
    };

    // 存放当前关联列表操作栏目
    const linkArticleForm = ref({});

    // 当前栏目下的列表
    const articleData = reactive({ dataSource: [], loading: false });

    // 分页数据
    const pagination = reactive({ limit: 10, page: 1, total: 0 });

    /**
     * 打开关联文章弹窗
     **/
    const getLinkArticle = async row => {
      linkArticleModal.visible = true;
      linkArticleForm.value = row;
      confirmGetLinkArticle();
    };

    /**
     * 获取关联列表文章
     **/
    const confirmGetLinkArticle = async () => {
      try {
        articleData.loading = true;
        const { page } = await apiGetArticleColList({
          columnId: linkArticleForm.value.id,
          page: pagination.page,
          limit: pagination.limit,
          type: 2,
        });
        articleData.dataSource = page.list;
        pagination.total = page.total;
      } finally {
        articleData.loading = false;
      }
    };

    /**
     * 关闭操作栏目弹窗
     **/
    const cancel = () => {
      showHandlerCol.value = false;
      colInfo.columnName = '';
      colInfo.parentId = 0;
      colInfo.id = '';
      colForm.value.resetFields();
    };

    /**
     * 栏目操作
     **/
    const colForm = ref();
    const confirmHandlerCol = () => {
      if (isLoading) return;
      colForm.value.validate().then(() => {
        const { columnName, columnType, parentId, id } = toRaw(colInfo);
        colInfo.id
          ? confirmEditCol({
              columnName,
              columnType,
              parentId: parentId || 0,
              columnId: id,
              type: 2,
            })
          : confirmAddCol({ columnName, columnType, parentId: parentId || 0, type: 2 });
      });
    };

    /**
     * 发送编辑栏目
     **/
    const confirmEditCol = async params => {
      try {
        isLoading = true;
        await apiEditColumn(params);
        message.success('编辑成功');
        confirmGetColumn();
        cancel();
      } finally {
        isLoading = false;
      }
    };

    /**
     * 发送添加栏目
     **/
    const confirmAddCol = async params => {
      try {
        isLoading = true;
        await apiAddColumn(params);
        message.success('新增栏目成功');
        confirmGetColumn();
        cancel();
      } finally {
        isLoading = false;
      }
    };

    /**
     * 删除栏目
     **/
    const confirmDelCol = () => {
      apiDelColumn({ columnId: colInfo.id, type: 2 }).then(() => {
        message.success('删除成功');
        colInfo.id = '';
        confirmGetColumn();
      });
    };

    const artSort = {};
    const changeArtSort = (e, row) => {
      artSort.number = e;
      artSort.info = toRaw(row);
    };

    /**
     * 更改排序
     **/
    const confirmArtSort = () => {
      if (!artSort.number) {
        return;
      }
      apiEditRelationdArticle({
        sequence: artSort.number,
        articleId: artSort.info.id,
        columnId: artSort.info.columnId,
        type: 2,
      }).then(() => {
        confirmGetLinkArticle();
        artSort.number = '';
        artSort.info = {};
      });
    };

    /**
     * 解除关联
     **/
    const dissociated = async form => {
      if (isLoading) return;
      try {
        const columnId = linkArticleForm.value.id;
        const articleId = form.id;
        isLoading = true;
        await apiDissociated({ type: 2, columnId, articleId });
        message.success('解除成功');
        confirmGetLinkArticle();
      } finally {
        isLoading = false;
      }
    };

    /**
     * 控制关联文章弹窗
     **/
    const linkArticleModal = reactive({ visible: false, title: '关联文章' });
    const closeLinkArticle = () => {
      linkArticleModal.visible = false;
      linkArticleForm.value = {};
    };

    const showColArticle = ref(false);
    const linkColArticle = () => {
      showColArticle.value = true;
    };

    /**
     * 关联文章校验
     **/
    const validLinkArticle = async () => {
      const articleIds = concatIds(linkArticleKey.articleIds);
      if (!articleIds) {
        return message.error('文章不能为空');
      } else {
        confirmLinkArticle();
      }
    };

    /**
     * 关联文章
     **/
    const confirmLinkArticle = async () => {
      const articleIds = concatIds(linkArticleKey.articleIds);
      const columnIds = linkArticleForm.value.id;
      if (isLoading) return;
      try {
        isLoading = true;
        await apiAddRelationdArticle({ articleIds, columnIds, type: 2 });
        closeColArticle();
        confirmGetLinkArticle();
        confirmGetColumn();
        message.success('关联成功');
      } finally {
        isLoading = false;
      }
    };

    /**
     * 关闭警告框
     **/
    const cancelWarning = () => {
      colInfo.id = '';
    };

    return {
      cancelWarning,
      colColumns,
      data,
      changeColSort,
      confirmColSort,
      editCol,
      delCol,
      changeStatus,
      addCol,
      pagination,
      getLinkArticle,
      showHandlerCol,
      colInfo,
      rules,
      cancel,
      confirmHandlerCol,
      title,
      delColWarning,
      confirmDelCol,
      linkArticleModal,
      articleColumns,
      changeArtSort,
      confirmArtSort,
      articleData,
      dissociated,
      closeLinkArticle,
      linkColArticle,
      showColArticle,
      articleList,
      validLinkArticle,
      rootColumn,
      confirmGetLinkArticle,
      confirmGetTagList,
      confirmGetArticle,
      searchArticleInfo,
      linkArticleKey,
      closeColArticle,
      tags,
      VUE_APP_YXT_URL: process.env.VUE_APP_YXT_URL,
      colForm,
      scollGetArticle,
    };
  },
  components: {
    WarningModal,
    ListTransfer,
  },
});
</script>
<style lang="less" scoped>
.iconfont {
  font-size: 14px;
}
.icon-xiayi12px {
  margin-left: 10px;
  // cursor: pointer;
}
</style>
